/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package au.com.gworks.jump.app.wiki.client.navigation;

import org.javaongems.client.Gem;
import org.javaongems.client.forms.Form;
import org.javaongems.client.stdctrls.Image;
import org.javaongems.client.stdctrls.MenuBar;
import org.javaongems.client.stdctrls.MenuItem;
import org.javaongems.client.rt.text.DateFormatUtils;
import org.javaongems.client.winctrls.ListView;
import org.javaongems.client.winctrls.ListViewColumnHeaderFormatter;
import org.javaongems.client.winctrls.ListViewDataSource;
import org.javaongems.client.winctrls.ListViewDetailViewStyle;


import au.com.gworks.jump.app.wiki.client.service.WikiRpc;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.HTMLTable.RowFormatter;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;

public class ExplorerForm extends Form {
	private DockPanel outerPanel = new DockPanel();
	private DockPanel locationBar = new DockPanel();
	private TabPanel viewSwitcher = new TabPanel();
	private HorizontalPanel iconPanel = new HorizontalPanel();
	private HorizontalPanel detailPanel = new HorizontalPanel();
	private ListView listView = new ListView();
	private ExplorerToolbar toolBar; 
	private ExplorerStyler styler = new ExplorerStyler();
	private MenuBar menuBar = new MenuBar();
	private MenuBar fileMenuBar = new MenuBar(true);
	private MenuBar editMenuBar = new MenuBar(true);
	/*pkg*/ MenuItem fileUpldMenuItem;
	/*pkg*/ MenuItem fileCloseMenuItem;
	
	
	private ExplorerDataSource			dataSource = new ExplorerDataSource();
	private ExplorerController 			controller;
	private WikiRpc.ExplorerInfo 	ctrlrModel;
	
	private String namespace, path;
	private Integer revision;
		
	public ExplorerForm(ExplorerController ctrlr) {
		super(ctrlr);
		controller = ctrlr;
		toolBar = new ExplorerToolbar(controller);
		initialiseLayout();
		initialiseWidgets();
		initialiseListeners();
	}
	
	private void initialiseLayout() {
		add(outerPanel);
		viewSwitcher.add(iconPanel, " icon ");
		viewSwitcher.add(detailPanel, " detail ");
		iconPanel.add(listView);
		outerPanel.add(menuBar, DockPanel.NORTH);
		outerPanel.add(toolBar, DockPanel.NORTH);
		outerPanel.add(locationBar, DockPanel.NORTH);
		outerPanel.add(viewSwitcher, DockPanel.CENTER);
		DOM.setAttribute(getElement(), "id", "jumpExplorerWindow");
	}
	
	private void initialiseWidgets() {
		listView.setDetailViewStyle(styler);
		viewSwitcher.selectTab(0);
		String imgPfx = Gem.stone.getApplImageCtx();
		com.google.gwt.user.client.ui.Image formIcon = new Image(imgPfx + "explore-x16.png");
		setFormIcon(formIcon);
		MenuItem fileNewFolderMenuItem = new MenuItem("New folder", false, (Command) null, false, imgPfx + "nfolder.gif");
		MenuItem fileNewDocMenuItem = new MenuItem("New document", false, (Command) null, false, imgPfx + "newDoc.gif");
		fileUpldMenuItem = new MenuItem("Upload document", false, (Command) null, true, imgPfx + "upload.gif");
		MenuItem fileLockMenuItem = new MenuItem("Lock", false, (Command) null, false, imgPfx + "lock.gif");
		MenuItem fileUnlockMenuItem = new MenuItem("Unlock", false, (Command) null, false, imgPfx + "unlock.gif");
		MenuItem fileDeleteMenuItem = new MenuItem("Delete", false, (Command) null, false, imgPfx + "delete.gif");
		MenuItem fileRenameMenuItem = new MenuItem("Rename", false, (Command) null);
		MenuItem filePropertiesMenuItem = new MenuItem("Properties", false, (Command) null);
		fileCloseMenuItem = new MenuItem("Close", false, (Command) null);
		fileMenuBar.addItem(fileNewFolderMenuItem);
		fileMenuBar.addItem(fileNewDocMenuItem);
		fileMenuBar.addItem(fileUpldMenuItem);
		fileMenuBar.addItem(MenuBar.createSeparator());
		fileMenuBar.addItem(fileLockMenuItem);
		fileMenuBar.addItem(fileUnlockMenuItem);
		fileMenuBar.addItem(MenuBar.createSeparator());
		fileMenuBar.addItem(fileDeleteMenuItem);
		fileMenuBar.addItem(fileRenameMenuItem);
		fileMenuBar.addItem(MenuBar.createSeparator());
		fileMenuBar.addItem(filePropertiesMenuItem);
		fileMenuBar.addItem(fileCloseMenuItem);
		menuBar.addItem(new MenuItem("File", fileMenuBar));
		menuBar.addItem(new MenuItem("Edit", editMenuBar));
	}
	
	private void initialiseListeners() {
		setFormActionListener(controller);
		listView.setViewListener(controller);
		viewSwitcher.addTabListener(controller);
		toolBar.setToolbarListener(controller);
		menuBar.setMenuBarListener(controller);
		fileMenuBar.setMenuBarListener(controller);
		editMenuBar.setMenuBarListener(controller);
	}
	
	public void setExplorerModel(WikiRpc.ExplorerInfo model) {
		ctrlrModel = model;
		setModel(model);
		listView.setDataSource(dataSource);
	}
	
	public void setContext(String ns, String pth, Integer rev) {
		namespace = ns;
		path = pth;
		revision = rev;
		toolBar.setFolderPath(path);
		updateWindowCaption();
	}
	
	public void show() {
		super.show();
		paint();
	}

	public void refresh() {
		super.refresh();
		paint();
	}
	
	private void paint() {
		listView.render();
		resizeListView();
	}
	
	private void updateWindowCaption() {
		String title = namespace + " (r" + revision.toString() + ")" + " - " + path;
		setCaption(title);
	}

	/*pkg*/ void resizeListView() {		// workaround of bug in listview resizing
		int width = getStatusBarWidth();
		int lbTop = listView.getAbsoluteTop();
		int sbTop = getStatusBarTop();
		int height = sbTop - lbTop;
		listView.onResize(width, height);
	}
	
	/*pkg*/ void switchToTab(int tabIndex) {
		if (tabIndex == 0) {
			detailPanel.remove(listView);
			iconPanel.add(listView);
		} else {
			iconPanel.remove(listView);
			detailPanel.add(listView);
		}
		listView.setViewMode(tabIndex==1);
		paint();
	}
		
	class ExplorerDataSource implements ListViewDataSource {
		public String getColumnDisplayName(int col) {
			switch (col) {
			case 0: return "Name";
			case 1: return "Size";
			case 2: return "Date modified";
			case 3: return "Author";
			case 4: return "Revision";
			}
			return null;
		}

		public int getColCount() { return 5; }
		public int getDataRowCount() {
			if (ctrlrModel == null)
				return 0;
			return ctrlrModel.subFolders.length + ctrlrModel.resources.length; 
		}

		public String getDisplayCellData(int row, int col) {
			String[] storeFolder = new String[1];
			WikiRpc.ResourceAttrInfo[] storeRes = new WikiRpc.ResourceAttrInfo[1];
			boolean resType = controller.getFolderResourceRowMapper(row, storeFolder, storeRes);
			String ret = "";
			if (resType) {
				switch (col) {
				case 0: ret = storeRes[0].name; break;
				case 1: ret = "" + storeRes[0].size; break;
				case 2: ret = DateFormatUtils.formatAsIsoDate(storeRes[0].lastModified); break;
				case 3: ret = storeRes[0].lastUpdater; break;
				case 4: ret = storeRes[0].revision.toString(); break;
				}
			} else {
				if (col == 0) ret = storeFolder[0];
			}
			return ret;
		}

		public Comparable getComparableCellData(int row, int col) {
			String[] storeFolder = new String[1];
			WikiRpc.ResourceAttrInfo[] storeRes = new WikiRpc.ResourceAttrInfo[1];
			boolean resType = controller.getFolderResourceRowMapper(row, storeFolder, storeRes);
			Comparable ret = "";
			if (resType) {
				switch (col) {
				case 0: ret = storeRes[0].name.toLowerCase(); break;
				case 1: ret = new Long(storeRes[0].size); break;
				case 2: ret = new Long(storeRes[0].lastModified); break;
				case 3: ret = storeRes[0].lastUpdater.toLowerCase(); break;
				case 4: ret = storeRes[0].revision; break;
				}
			} else {
				switch (col) {
				case 0: ret = storeFolder[0].toLowerCase(); break;
				case 3: ret = ""; break;
				case 1:
				case 2: ret = new Long(0); break;
				case 4: ret = new Integer(0); break;
				}
			}
			return ret;
		}

		public String getDetailViewImageUrl(int row) {
			boolean resType = controller.getFolderResourceRowMapper(row, null, null);
			String res = resType ? "resource-x16.png": "folder-x16.png";
			return Gem.stone.getApplImageCtx() + res;
		}

		public String getIconViewImageUrl(int row) {
			boolean resType = controller.getFolderResourceRowMapper(row, null, null);
			String res = resType ? "resource-x64.png": "folder-x64.png";
			return Gem.stone.getApplImageCtx() + res;
		}
	}
	
	/*pkg*/ class ExplorerStyler implements ListViewDetailViewStyle {
		public void styleHeader(int col, ListViewColumnHeaderFormatter frmtr) {
			boolean rightAl = col == 1 || col == 4; 
			HorizontalAlignmentConstant h = (rightAl ? HasHorizontalAlignment.ALIGN_RIGHT: HasHorizontalAlignment.ALIGN_LEFT);
			frmtr.setAlignment(col, h, HasVerticalAlignment.ALIGN_MIDDLE);
		}

		public void styleRow(int[] sortedDataSrcMap, int[] dataSrcSortedMap, int gridRow, RowFormatter frmtr) {
		}

		public void styleCell(int[] sortedDataSrcMap, int[] dataSrcSortedMap, int gridRow, int gridCol, CellFormatter frmtr) {
			boolean rightAl = gridCol == 1 || gridCol == 4; 
			HorizontalAlignmentConstant h = (rightAl ? HasHorizontalAlignment.ALIGN_RIGHT: HasHorizontalAlignment.ALIGN_LEFT);
			frmtr.setAlignment(gridRow, gridCol, h, HasVerticalAlignment.ALIGN_MIDDLE);
		}
	}
}
